<template>
  <div class="app-container">
    <div>
      <el-tabs v-model="activeTab" type="border-card" @tab-click="handleClick">
        <el-tab-pane label="info" name="info">
          <keep-alive>
            <div class="inline-box">
              <el-form ref="form" :model="form" label-width="80px">
                <el-form-item label="用例名称" required>
                  <el-col :span="10">
                    <el-input v-model="form.name" label="用例名称" />
                  </el-col>
                </el-form-item>
                <el-form-item label="项目" required>
                  <el-select
                    v-model="form.belong_project"
                    :disabled="operation_type === 1 ? true:false"
                    filterable
                    clearable
                    placeholder="用例所属项目"
                    @change="projectChange"
                  >
                    <el-option
                      v-for="item in project_options"
                      :key="item.id"
                      :label="item.project_name"
                      :value="item.id"
                    />
                  </el-select>
                </el-form-item>
                <el-form-item label="模块" required>
                  <el-select
                    v-model="form.belong_module"
                    filterable
                    clearable
                    placeholder="用例所属模块"
                    @change="info_moduleChange"
                  >
                    <el-option
                      v-for="item in data_options.module_list"
                      :key="item.id"
                      :label="item.module_name"
                      :value="item.id"
                    />
                  </el-select>
                </el-form-item>
                <el-form-item label="认证用户">
                  <el-select v-model="form.auth" filterable placeholder="用例认证用户">
                    <el-option
                      v-for="item in data_options.auth_list"
                      :key="item.id"
                      :label="item.name"
                      :value="item.id"
                    />
                  </el-select>
                </el-form-item>
              </el-form>
            </div>
          </keep-alive>
        </el-tab-pane>
        <el-tab-pane label="pre-case" name="pre-case">
          <keep-alive>
            <div class="flex-box">
              <div class="inline-box">
                <el-form ref="form" :model="form" label-width="80px">
                  <el-form-item label="项目">
                    <el-select
                      v-model="form.belong_project"
                      disabled
                      placeholder="前置用例所属项目"
                    >
                      <el-option
                        v-for="(item) in project_options"
                        :key="item.id"
                        :label="item.project_name"
                        :value="item.id"
                      />
                    </el-select>
                  </el-form-item>
                  <el-form-item label="模块">
                    <el-select
                      v-model="data_options.pre_case_module"
                      filterable
                      placeholder="前置用例所属模块"
                      @change="precase_moduleChange"
                    >
                      <el-option
                        v-for="item in data_options.module_list"
                        :key="item.id"
                        :label="item.module_name"
                        :value="item.id"
                      />
                    </el-select>
                  </el-form-item>
                  <el-form-item label="预置用例选项用例">
                    <el-table
                      v-loading="data_options.pre_case_list_Loading"
                      :data="data_options.pre_case_list"
                      element-loading-text="Loading"
                      border
                      fit
                      :row-class-name="tableRowClassName"
                      @row-click="rowClick"
                    >
                      <el-table-column
                        prop="id"
                        label="用例ID"
                        min-width="20%"
                        show-overflow-tooltip
                      />
                      <el-table-column
                        prop="name"
                        label="用例名称"
                        sortable
                        min-width="80%"
                        show-overflow-tooltip
                      />
                    </el-table>
                  </el-form-item>
                  <el-pagination
                    background
                    layout="prev, pager, next"
                    :total="data_options.pre_case_list_pagination.total"
                    @current-change="handleCurrentChange"
                  />
                </el-form>
              </div>
              <span>
                <i class="el-icon-d-arrow-right" />
              </span>
              <div class="inline-box">
                <label>预置执行用例列表:</label>
                <br>
                <tableList
                  ref="TableList"
                  :columns-text="pre_case_column"
                  :list_data="form.pre_cases"
                  @changeList="changePreCasesLists"
                />
              </div>
            </div>
          </keep-alive>
        </el-tab-pane>
        <el-tab-pane label="request" name="request">
          <keep-alive>
            <el-form ref="form" :model="form" label-width="150px">
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-input
                    v-model="form.request.test.request.url"
                    placeholder="api url"
                  >
                    <template slot="prepend">URL</template>
                  </el-input>
                </el-col>
                <el-col :span="2">
                  <el-select v-model="form.request.test.request.method" placeholder="Select Method">
                    <el-option label="POST" value="POST" />
                    <el-option label="GET" value="GET" />
                    <el-option label="PUT" value="PUT" />
                    <el-option label="DELETE" value="DELETE" />
                  </el-select>
                </el-col>
                <el-col :span="2">
                  <el-select
                    v-model="form.request.test.request.type"
                    placeholder="Select Data type"
                    @change="typeChange"
                  >
                    <el-option label="data" value="data" />
                    <el-option label="json" value="json" />
                    <el-option label="params" value="params" />
                  </el-select>
                </el-col>
              </el-row>
              <br>
              <div v-if="form.request.test.request.type === 'params'" key="params">
                <tableSelect
                  v-if="getinfo_flag || !operation_type"
                  ref="TableSelectParams"
                  :table-type="'Params'"
                  :datas-text.sync="form.request.test.request.content"
                  @changeList="changeParamsLists"
                />
              </div>
              <div v-else-if="form.request.test.request.type === 'data'" key="data">
                <tableSelect
                  v-if="getinfo_flag || !operation_type"
                  ref="TableSelectData"
                  :table-type="'Data'"
                  :datas-text.sync="form.request.test.request.content"
                  @changeList="changeDataLists"
                />
              </div>
              <div v-else>
                <div v-if="getinfo_flag || !operation_type">
                  <b-code-editor
                    ref="editor"
                    v-model="form.request.test.request.content"
                    theme="rubyblue"
                    :auto-format="true"
                    :indent-unit="4"
                    :smart-indent="true"
                    :line-wrap="true"
                  />
                </div>
                <el-button
                  type="success"
                  @click="$refs['editor'].formatCode()"
                >格式化JSON
                </el-button>
                <el-button
                  type="success"
                  @click="validateJSON"
                >校验JSON
                </el-button>
              </div>
              <br>
              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Headers'"
                :datas-text.sync="form.request.test.request.headers"
                @changeList="changeHeadersLists"
              />
            </el-form>
          </keep-alive>
        </el-tab-pane>
        <el-tab-pane label="extract/validate" name="extract/validate">
          <keep-alive>
            <el-form ref="form" :model="form" label-width="120px">
              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Extract'"
                :datas-text.sync="form.request.test.extract"
                style="margin-bottom: 15px"
                @changeList="changeExtractLists"
              />

              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Validate'"
                :datas-text.sync="form.request.test.validate"
                @changeList="changeValidateLists"
              />
            </el-form>
          </keep-alive>
        </el-tab-pane>
        <el-tab-pane label="variables/parameters/hooks" name="variables/parameters/hooks">
          <keep-alive>
            <el-form ref="form" :model="form" label-width="120px">
              <br>
              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Variables'"
                :datas-text.sync="form.request.test.variables"
                style="margin-top: -15px"
                @changeList="changeVariablesLists"
              />
              <br>
              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Parameters'"
                :datas-text.sync="form.request.test.parameters"
                style="margin-top: -15px"
                @changeList="changeParametersLists"
              />
              <br>
              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Setup Hooks'"
                :datas-text.sync="form.request.test.setup_hooks"
                style="margin-top: -15px"
                @changeList="changeSetupHooksLists"
              />
              <br>
              <tableSelect
                v-if="getinfo_flag || !operation_type"
                ref="TableSelect"
                :table-type="'Teardown Hooks'"
                :datas-text.sync="form.request.test.teardown_hooks"
                style="margin-top: -15px"
                @changeList="changeTeardownHooksLists"
              />
            </el-form>
          </keep-alive>
        </el-tab-pane>
      </el-tabs>
    </div>
    <br>
    <div style="text-align: center">
      <el-button type="success" @click="onSubmit">保存</el-button>
      <el-button @click="onCancel">取消</el-button>
    </div>
  </div>
</template>

<script>
import tableSelect from '@/components/tableSelect'
import tableList from '@/components/tableList'
import { getProjectSumList } from '@/api/project/table'
import { getModuleSumList } from '@/api/module/table'
import { getAuthList } from '@/api/test_auth/table'
import { createCase, getCase, updateCase, getCaseList } from '@/api/test_case/table'

const jsonData = '{"key": "value"}'

export default {
  components: {
    tableSelect,
    tableList
  },
  data() {
    return {
      operation_type: 0, // 0:create 1:update 2:copy
      caseID: '',
      getinfo_flag: false,

      activeTab: 'info',
      form: {
        name: '',
        belong_project: '',
        belong_module: '',
        auth: '',
        pre_cases: [],
        request: {
          test: {
            request: {
              url: '',
              method: 'POST',
              type: 'data',
              content: [
                // {
                //   id: '1',
                //   inputKey: 'data123',
                //   selectType: 'string',
                //   inputValue: 'data134'
                // }
              ],
              headers: [
              /* {
                  id: '1',
                  inputKey: 'headers123',
                  inputValue: '134'
                },
                {
                  id: '2',
                  inputKey: 'headers223',
                  inputValue: '234'
                }*/
              ]
            },
            extract: [
            /* {
                id: '1',
                inputKey: 'extract12',
                inputValue: '34'
              },
              {
                id: '2',
                inputKey: 'extract22',
                inputValue: '324'
              }*/
            ],
            validate: [
            /* {
                id: '1',
                inputCheck: 'json.data.validate1',
                selectComparator: 'equals',
                selectType: 'string',
                inputExpected: 'v34'
              },
              {
                id: '2',
                inputCheck: 'json.data.validate2',
                selectComparator: 'equals',
                selectType: 'string',
                inputExpected: 'v324'
              }*/
            ],
            variables: [
            /* {
                id: '1',
                inputKey: 'variables12',
                selectType: 'string',
                inputValue: '34'
              },
              {
                id: '2',
                inputKey: 'variables22',
                selectType: 'string',
                inputValue: '324'
              }*/
            ],
            parameters: [
            /* {
                id: '1',
                inputKey: 'user',
                inputValue: '["test1", "test2"]'
              },
              {
                id: '2',
                inputKey: 'usr-pwd',
                inputValue: '[["test1", "pwd1"], ["test2", "pwd2"]]'
              }*/
            ],
            setup_hooks: [
            /* {
                id: '1',
                selectHooks: 'execute_sql',
                inputValue: '$s34'
              },
              {
                id: '2',
                selectHooks: 'execute_sql',
                inputValue: '$s324'
              }*/
            ],
            teardown_hooks: [
            /* {
                id: '1',
                selectHooks: 'execute_sql',
                inputValue: '$t34'
              },
              {
                id: '2',
                selectHooks: 'execute_sql',
                inputValue: '$t324'
              }*/
            ]
          }
        },
        author: ''
      },
      project_options: [],
      data_options: {
        module_list: [],
        auth_list: [], // 用例 auth_list
        pre_case_module: '', // 预置用例的模块(可以和用例模块不一致，且不用存储)
        pre_case_list: [], // 预置用例的可选列表
        pre_case_list_pagination: {
          total: 0,
          page_current: 1,
          page_num: 1,
          page_size: 10
        },
        pre_case_list_Loading: false
      },
      pre_case_column: [
        {
          label: '用例ID',
          prop: 'id',
          minWidth: '15%',
          valueKey: 'id'
        },
        {
          label: '用例名称',
          prop: 'name',
          minWidth: '70%',
          valueKey: 'name'
        }
      ],
      list_data: []
    }
  },
  created() {
    this.operation_type = this.$route.query.operation_type || 0
    this.caseID = this.$route.query.id || ''
    console.log('Opertaion Type: ' + this.operation_type)
    console.log('caseID: ' + this.caseID)

    if (this.operation_type !== 0) {
      this.getData() // 编辑或复制
    } else {
      this.fetchProjectSumList() // 新增
    }
  },
  mounted() {
    this.operation_type = this.$route.query.operation_type || 0
    this.caseID = this.$route.query.id || ''
    console.log('Opertaion Type: ' + this.operation_type)
    console.log('Update or Copy caseID: ' + this.caseID)
  },
  methods: {
    getCaseData() {
      var params = {}
      params['id'] = this.caseID
      return new Promise((resolve, reject) => {
        getCase(params).then(response => {
          this.form = response.data
          this.getinfo_flag = response.success
          resolve(response)
        }).catch(e => {
          reject(e)
        })
      })
    },
    fetchProjectSumList() {
      return new Promise((resolve, reject) => {
        getProjectSumList().then((response) => {
          this.project_options = response.results
          resolve(response)
        }).catch(e => {
          reject(e)
        })
      })
    },
    fetchModuleSumList() {
      console.log('获取信息模块信息时的项目ID : ' + this.form.belong_project)
      var params = { 'belong_project': this.form.belong_project }
      return new Promise((resolve, reject) => {
        getModuleSumList(params).then((response) => {
          this.data_options.module_list = response.results
          resolve(response)
        }).catch(e => {
          reject(e)
        })
      })
    },
    async getData() {
      await this.getCaseData()
      await this.fetchProjectSumList()
      await this.fetchModuleSumList()
      await this.fetchAuthSumList()
    },
    fetchInfoModuleList() {
      console.log('获取模块信息时的项目ID : ' + this.form.belong_project)
      if (this.form.belong_project) {
        var params = { 'belong_project': this.form.belong_project }
        getModuleSumList(params).then(response => {
          this.data_options.module_list = response.results
        })
      }
    },
    fetchAuthSumList() {
      console.log('获取模块信息时的项目ID : ' + this.form.belong_project)
      if (this.form.belong_project) {
        var params = { 'belong_project': this.form.belong_project }
        getAuthList(params).then(response => {
          this.data_options.auth_list = response.results
        })
      }
    },
    fetchPreCaseList: function() {
      if (this.form.belong_project && this.data_options.pre_case_module) {
        var params = {
          'belong_project': this.form.belong_project,
          'belong_module': this.data_options.pre_case_module,
          'page_num': this.data_options.pre_case_list_pagination.page_num,
          'ordering': '-update_time'
        }

        this.data_options.pre_case_list_Loading = true

        return new Promise((resolve, reject) => {
          getCaseList(params).then(response => {
            this.data_options.pre_case_list = response.results
            this.data_options.pre_case_list_pagination.total = response.count
            this.data_options.pre_case_list_Loading = false
          }).then((data) => {
            this.optionalCaseListChange()
          }).catch(e => {
            reject(e)
          })
        })
      }
    },
    handleCurrentChange: function(val) { // 可选用例列表翻页
      this.data_options.pre_case_list_pagination.page_num = val
      this.fetchPreCaseList()
    },
    optionalCaseListChange: function() { // 可选用例列表变更
      if (this.form.pre_cases.length) {
        for (var i = 0; i < this.data_options.pre_case_list.length; i++) {
          for (var j = 0; j < this.form.pre_cases.length; j++) {
            if (this.data_options.pre_case_list[i].id === this.form.pre_cases[j].id) {
              this.$set(this.data_options.pre_case_list[i], 'class_name', 'selected')
            }
          }
        }
      }
    },
    handleClick(tab, event) {
      console.log('Switch Tab to : ' + this.activeTab)
    },
    typeChange() {
      console.log('Request Type : ' + this.form.request.test.request.type)
      if (this.form.request.test.request.type === 'json') {
        console.log('Request content : ' + this.form.request.test.request)
        this.form.request.test.request.content = jsonData
      }
      if (this.form.request.test.request.type === 'data') {
        this.form.request.test.request.content = []
      }
      if (this.form.request.test.request.type === 'params') {
        this.form.request.test.request.content = []
      }
    },
    validateJSON() {
      if (this.form.request.test.request.type === 'json') {
        var str = this.form.request.test.request.content
        if (typeof str === 'string') {
          try {
            var obj = JSON.parse(str)
            if (typeof obj === 'object' && obj) {
              this.$message.info(`json格式正确`)
              return true
            } else {
              this.$message.error(`json格式错误,请修正后再提交`)
              return false
            }
          } catch (e) {
            this.$message.error(`json格式错误,请修正后再提交`)
            return false
          }
        } else if (typeof str === 'object' && str) {
          this.$message.error(`json格式错误,请修正后再提交`)
          return true
        }
      }
    },
    onSubmit() {
      this.validateJSON()

      if (this.operation_type.toString() === '1') {
        updateCase(this.form).then(response => {
          if (response.status === '000000') return
          this.$message.success('更新成功')
          this.$router.replace(`/test_case/case_list`)
        })
      } else {
        createCase(this.form).then(response => {
          if (response.status === '000000') return
          this.$message.success('创建成功')
          this.$router.replace(`/test_case/case_list`)
        })
      }
    },
    onCancel() {
      this.$confirm('此操作将退出编辑, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$router.replace(`/test_case/case_list`)
        this.$message({
          type: 'success',
          message: '退出成功!'
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消退出'
        })
      })
    },
    projectChange() {
      // 1、项目切换，需要清空用例所属模块、预置用例模块、预置用例可选用例、预置用例列表
      console.log('Project' + this.form.belong_project)
      this.form.belong_module = ''
      this.form.auth = ''
      this.data_options.auth_list = []
      this.data_options.pre_case_module = ''
      this.data_options.pre_case_case_list = []
      this.form.pre_cases = []

      // 2、再重新获取用例所属模块和预置用例所属模块
      this.fetchInfoModuleList()
      this.fetchAuthSumList()
    },
    info_moduleChange() {
      // http请求
      console.log('Info Project:' + this.form.belong_project)
      console.log('Info Module:' + this.form.belong_module)
      // 获取项目对应的auth列表
    },
    precase_moduleChange(val) {
      // http请求
      console.log('PreCase Module:' + this.data_options.pre_case_module)
      this.data_options.pre_case_list = []
      this.fetchPreCaseList()
    },
    caseChange: function(val) {
      console.log(val)
      var item = this.data_options.pre_case_list.filter(item => item.index === val)[0]
      console.log(item)
      if (item) {
        var counter = 0
        for (var i = 0; i < this.form.pre_cases.length; i++) {
          if (item.index === this.form.pre_cases[i].index) {
            counter++
          }
        }
        if (counter >= 1) {
          this.$message({
            message: '提示:[' + item.name + '] , 在预置用例列表中已存在！',
            type: 'info'
          })
        } else {
          this.form.pre_cases.push(item)
        }
      }
    },
    getCaseInfo() {
      var params = {}
      params['id'] = this.caseID

      getCase(params).then(response => {
        this.form = response.data
        this.getinfo_flag = response.success
      })
    },
    rowClick: function(row) {
      var item = this.data_options.pre_case_list.filter(item => item.id === row.id)[0]
      console.log('选中项如下：')
      console.log(item)
      if (item) {
        var counter = 0
        for (var i = 0; i < this.form.pre_cases.length; i++) {
          if (item.id === this.form.pre_cases[i].id) {
            counter++
          }
        }
        if (counter >= 1) {
          this.$message({
            message: '提示：[' + item.name + '] , 在预置用例列表中已存在！',
            type: 'info'
          })
        } else {
          this.form.pre_cases.push(JSON.parse(JSON.stringify(item)))
          this.$set(row, 'class_name', 'selected')
        }
      }
    },
    tableRowClassName: function({ row, rowIndex }) {
      console.log(row.class_name)
      if (row.class_name !== 'selected') {
        return ''
      } else {
        return 'success-row'
      }
    },

    changePreCasesLists: function(obj) {
      this.form.pre_cases = obj.list

      if (obj.item) {
        for (var i = 0; i < this.data_options.pre_case_list.length; i++) {
          if (this.data_options.pre_case_list[i].id === obj.item.id) {
            this.$set(this.data_options.pre_case_list[i], 'class_name', '')
          }
        }
      }
    },
    changeDataLists: function(obj) {
      this.form.request.test.request.content = obj.list
    },
    changeParamsLists: function(obj) {
      this.form.request.test.request.content = obj.list
    },
    changeHeadersLists: function(obj) {
      this.form.request.test.request.headers = obj.list
    },
    changeExtractLists: function(obj) {
      this.form.request.test.extract = obj.list
    },
    changeValidateLists: function(obj) {
      this.form.request.test.validate = obj.list
    },
    changeVariablesLists: function(obj) {
      this.form.request.test.variables = obj.list
    },
    changeParametersLists: function(obj) {
      this.form.request.test.parameters = obj.list
    },
    changeSetupHooksLists: function(obj) {
      this.form.request.test.setup_hooks = obj.list
    },
    changeTeardownHooksLists: function(obj) {
      this.form.request.test.teardown_hooks = obj.list
    }
  }
}
</script>

<style scoped lang="scss">
.el-table .success-row {
  background: #f0f9eb;
}

.line {
  text-align: center;
}

.flex-box {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-content: center;

  .inline-box {
    display: inline-block;
    width: 40%;

    &:last-child {
      width: 500px;
    }
  }

  > span {
    font-size: 30px;
    line-height: 290px;
  }
}

</style>

